package com.jzo2o.health.service.impl;

import cn.hutool.core.bean.BeanUtil;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.api.trade.enums.RefundStatusEnum;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersCancelledMapper;
import com.jzo2o.health.mapper.OrdersMapper;

import com.jzo2o.health.mapper.OrdersRefundMapper;
import com.jzo2o.health.model.UserThreadLocal;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.model.dto.request.OrdersPageQueryReqDTO;
import com.jzo2o.health.model.dto.response.AdminOrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersCountResDTO;
import com.jzo2o.health.model.dto.response.OrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersResDTO;
import com.jzo2o.health.service.IOrdersService;

import com.jzo2o.mysql.utils.PageHelperUtils;

import org.redisson.Redisson;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class IOrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private OrdersCancelledMapper ordersCancelledMapper;
    @Resource
    private OrdersRefundMapper ordersRefundMapper;
    @Resource
    private RefundRecordApi refundRecordApi;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 管理端分页查询订单
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<OrdersResDTO> pageQuery(OrdersPageQueryReqDTO dto) {
        //分页查询
        List<Long> ids = dto.getIds();
        PageResult<OrdersResDTO> pageResult = PageHelperUtils.selectPage(dto, () -> ordersMapper.pageQuery(ids, dto.getOrderStatus(), dto.getMemberPhone()));
        String memberPhone = dto.getMemberPhone();
        //将号码存入缓存给统计状态使用
        redisTemplate.opsForValue().set("memberPhone",memberPhone, Duration.ofSeconds(5));
        return pageResult;
    }

    /**
     * 根据订单id查询
     *
     * @param id
     * @return
     */
    @Override
    public AdminOrdersDetailResDTO aggregation(Long id) {
        //根据订单ID先查询订单详情，然后判空
        Orders orders = getById(id);
        if (orders == null) {
            throw new ForbiddenOperationException("订单不存在");
        }
        //订单取消表根据订单ID去查
        OrdersCancelled ordersCancelled = ordersCancelledMapper.selectById(id);
        //订单退款信息根据支付服务交易单号trading_order_no 查
        OrdersRefund ordersRefund = ordersRefundMapper.selectByTradingOrderNo(orders.getTradingOrderNo());
        //查询退款状态

        AdminOrdersDetailResDTO dto = new AdminOrdersDetailResDTO();
        AdminOrdersDetailResDTO.OrderInfo orderInfo = new AdminOrdersDetailResDTO.OrderInfo();
        AdminOrdersDetailResDTO.PayInfo payInfo = new AdminOrdersDetailResDTO.PayInfo();
        AdminOrdersDetailResDTO.RefundInfo refundInfo = new AdminOrdersDetailResDTO.RefundInfo();
        AdminOrdersDetailResDTO.CancelInfo cancelInfo = new AdminOrdersDetailResDTO.CancelInfo();
        //组装订单信息
        orderInfo.setId(orders.getId());
        orderInfo.setOrderStatus(orders.getOrderStatus());
        orderInfo.setSetmealId(orders.getSetmealId());
        orderInfo.setSetmealName(orders.getSetmealName());
        orderInfo.setSetmealPrice(orders.getSetmealPrice());
        orderInfo.setReservationDate(orders.getReservationDate());
        orderInfo.setCheckupPersonName(orders.getCheckupPersonName());
        orderInfo.setCheckupPersonSex(orders.getCheckupPersonSex());
        orderInfo.setCheckupPersonPhone(orders.getCheckupPersonPhone());
        orderInfo.setCheckupPersonIdcard(orders.getCheckupPersonIdcard());
        orderInfo.setMemberId(orders.getMemberId());
        orderInfo.setMemberPhone(orders.getMemberPhone());
        orderInfo.setCreateTime(orders.getCreateTime());
        dto.setOrderInfo(orderInfo);
        //组装支付信息
        payInfo.setPayStatus(orders.getPayStatus());
        payInfo.setThirdOrderId(orders.getTransactionId());
        payInfo.setTradingChannel(orders.getTradingChannel());
        payInfo.setPayTime(orders.getPayTime());
        dto.setPayInfo(payInfo);
        //组装退款信息
        //判断退款状态
        if (ObjectUtils.isNotEmpty(ordersRefund)) {
            ExecutionResultResDTO res = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
            Integer refundStatus = res.getRefundStatus();
            if (ObjectUtils.equal(refundStatus, RefundStatusEnum.SENDING.getCode())) {
                refundInfo.setRefundStatus(OrderPayStatusEnum.REFUNDING.getStatus());
            } else if (ObjectUtils.equal(refundStatus, RefundStatusEnum.SUCCESS.getCode())) {
                refundInfo.setRefundStatus(OrderPayStatusEnum.REFUND_SUCCESS.getStatus());
            } else if (ObjectUtils.equal(refundStatus, RefundStatusEnum.FAIL.getCode())) {
                refundInfo.setRefundStatus(OrderPayStatusEnum.REFUND_FAIL.getStatus());
            }
            refundInfo.setRefundId(res.getRefundId());
            refundInfo.setTradingChannel(orders.getTradingChannel());
            refundInfo.setCancelTime(ordersCancelled.getCancelTime());
            refundInfo.setCancelReason(ordersCancelled.getCancelReason());
        }
        dto.setRefundInfo(refundInfo);
        //组装订单取消理由
        if (ObjectUtils.isNotEmpty(ordersCancelled)) {
            cancelInfo.setCancelReason(ordersCancelled.getCancelReason());
            cancelInfo.setCancelTime(ordersCancelled.getCancelTime());
        }
        dto.setCancelInfo(cancelInfo);
        return dto;
    }

    /**
     * 根据状态统计数量
     * @return
     */
    @Override
    public OrdersCountResDTO countByStatus() {
        OrdersCountResDTO dto = new OrdersCountResDTO();
/*        //查询待支付数量
        Integer noPayCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.NO_PAY.getStatus()).count();
        dto.setNoPayCount(noPayCount);
        //查询待体检数量
        Integer waitingCheckupCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.WAITING_CHECKUP.getStatus()).count();
        dto.setWaitingCheckupCount(waitingCheckupCount);
        //查询已体检数量
        Integer competeCheckupCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.COMPLETED_CHECKUP.getStatus()).count();
        dto.setCompletedCheckupCount(competeCheckupCount);
        //查询已关闭数量
        Integer closedCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.CLOSED.getStatus()).count();
        dto.setClosedCount(closedCount);
        //查询已取消数量
        Integer cancelledCout = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.CANCELLED.getStatus()).count();
        dto.setCancelledCount(cancelledCout);
        //查询全部数量
        Integer totalCount = lambdaQuery().count();
        dto.setTotalCount(totalCount);*/


       String memberPhone = (String) redisTemplate.opsForValue().get("memberPhone");
        if (StrUtil.isNotBlank(memberPhone)) {
            //查询待支付数量
            Integer noPayCount = lambdaQuery().eq(Orders::getMemberPhone,memberPhone)
                    .eq(Orders::getOrderStatus, OrderStatusEnum.NO_PAY.getStatus()).count();
            dto.setNoPayCount(noPayCount);
            //查询待体检数量
            Integer waitingCheckupCount = lambdaQuery().eq(Orders::getMemberPhone,memberPhone).eq(Orders::getOrderStatus, OrderStatusEnum.WAITING_CHECKUP.getStatus()).count();
            dto.setWaitingCheckupCount(waitingCheckupCount);
            //查询已体检数量
            Integer competeCheckupCount = lambdaQuery().eq(Orders::getMemberPhone,memberPhone).eq(Orders::getOrderStatus, OrderStatusEnum.COMPLETED_CHECKUP.getStatus()).count();
            dto.setCompletedCheckupCount(competeCheckupCount);
            //查询已关闭数量
            Integer closedCount = lambdaQuery().eq(Orders::getMemberPhone,memberPhone).eq(Orders::getOrderStatus, OrderStatusEnum.CLOSED.getStatus()).count();
            dto.setClosedCount(closedCount);
            //查询已取消数量
            Integer cancelledCout = lambdaQuery().eq(Orders::getMemberPhone,memberPhone).eq(Orders::getOrderStatus, OrderStatusEnum.CANCELLED.getStatus()).count();
            dto.setCancelledCount(cancelledCout);
            //查询全部数量
            Integer totalCount = lambdaQuery().eq(Orders::getMemberPhone,memberPhone).count();

            dto.setTotalCount(totalCount);
        }else {  //查询待支付数量
            Integer noPayCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.NO_PAY.getStatus()).count();
            dto.setNoPayCount(noPayCount);
            //查询待体检数量
            Integer waitingCheckupCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.WAITING_CHECKUP.getStatus()).count();
            dto.setWaitingCheckupCount(waitingCheckupCount);
            //查询已体检数量
            Integer competeCheckupCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.COMPLETED_CHECKUP.getStatus()).count();
            dto.setCompletedCheckupCount(competeCheckupCount);
            //查询已关闭数量
            Integer closedCount = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.CLOSED.getStatus()).count();
            dto.setClosedCount(closedCount);
            //查询已取消数量
            Integer cancelledCout = lambdaQuery().eq(Orders::getOrderStatus, OrderStatusEnum.CANCELLED.getStatus()).count();
            dto.setCancelledCount(cancelledCout);
            //查询全部数量
            Integer totalCount = lambdaQuery().count();
            dto.setTotalCount(totalCount);
        }
        return dto;
    }

    /**
     * 滚动分页查询
     * @param ordersStatus
     * @param sortBy
     * @return
     */
    @Override
    public List<OrdersResDTO> userPageQuery(Integer ordersStatus, Long sortBy) {
        Long memberId = UserThreadLocal.currentUserId();
        List<OrdersResDTO> list = ordersMapper.userPageQuery(memberId,ordersStatus,sortBy);
        List<OrdersResDTO> newList = list.stream().limit(10).collect(Collectors.toList());
        if (CollUtils.isEmpty(list)){
            return Collections.emptyList();
        }
        return newList;
    }

    /**
     * 用户根据订单id查询
     * @param id
     * @return
     */
    @Override
    public OrdersDetailResDTO getByOrderId(Long id) {
        Orders orders = getById(id);
        OrdersDetailResDTO dto = BeanUtil.toBean(orders, OrdersDetailResDTO.class);
        OrdersCancelled ordersCancelled = ordersCancelledMapper.selectById(id);
        if (ordersCancelled!=null){
            dto.setCancelTime(ordersCancelled.getCancelTime());
            dto.setCancelReason(ordersCancelled.getCancelReason());
        }
        return dto;
    }
}
